/************************************************************
       (@_       
  _     ) \_______________________________________________
 (_)@8@8{}<_______________________________________________>
        )_/        
       (@
Liuxp
Website:        http://me.alipay.com/liuxp
Version：       1.2
File name：     PublishFileVersionService.cs
Author：        刘小平
Date：          ‎2014年‎09‎月1‎0‎日，‏‎11:07:40
Description：   项目文件版本信息
History：       暂无
***********************************************************/
using System;
using System.Net;
using System.Linq;
using System.Text;
using Publish.Utility;
using System.Threading;
using System.Collections.Generic;

namespace Publish.Services
{
    /// <summary>
    /// 发布文件版本信息
    /// </summary>
    public class PublishFileVersionService : Service
    {
        #region Fields

        //新增项目文件版本信息 
        private const String InsertSql = "INSERT INTO [master].[dbo].[PublishFileVersion]([ProjectName],[LastWriteTime],[Size],[Path],[CreatorIPv4],[CreatorHostName],[CreatedTime],[ModifierIPv4],[ModifierHostName],[ModifiedTime])VALUES(N'{0}',N'{1}',N'{2}',N'{3}',N'{4}',N'{5}',GETDATE(),N'{4}',N'{5}',GETDATE())";
        //删除项目文件版本信息
        private const String DeleteSql = "DELETE FROM [master].[dbo].[PublishFileVersion]WHERE[ProjectName]=N'{0}' AND[Path]=N'{1}'";
        //删除项目文件版本信息
        //private const String DeleteByProjectNameSql = "DELETE FROM [master].[dbo].[PublishFileVersion]WHERE[ProjectName]=N'{0}'";

        //获取一条数据，看看最后更新时间
        private const String GetLastModifiedTimeSql = "SELECT TOP 1 ModifiedTime FROM [master].[dbo].[PublishFileVersion] WHERE ProjectName = N'{0}' ORDER BY ModifiedTime DESC";
        //根据项目名称获取该项目文件版本信息
        private const String GetFilesByPathSql = "SELECT[Id],[ProjectName],[LastWriteTime],[Size],[Path],[CreatorIPv4],[CreatorHostName],[CreatedTime],[ModifierIPv4],[ModifierHostName],[ModifiedTime]FROM [master].[dbo].[PublishFileVersion]WHERE[ProjectName]=N'{0}'";
        //根据项目名称获取该项目文件版本信息
        private const String GetAllFilesByProjectNameSql = "SELECT[Id],[ProjectName],[LastWriteTime],[Size],[Path],[CreatorIPv4],[CreatorHostName],[CreatedTime],[ModifierIPv4],[ModifierHostName],[ModifiedTime]FROM [master].[dbo].[PublishFileVersion]WHERE[ProjectName]=N'{0}'";

        private static readonly ModelHandler<Files> modelHandler = new ModelHandler<Files>();

        #endregion

        #region Constructors

        /// <summary>
        /// 
        /// </summary>
        static PublishFileVersionService()
        {
        }

        #endregion

        #region Public Method

        #region Thread Method

        /// <summary>
        /// 更新项目文件版本信息
        /// </summary>
        public static void UpdateThreadStart()
        {
            var bindDataThread = new Thread(Update) { IsBackground = true };
            bindDataThread.Start();//更新项目文件版本信息
        }

        #endregion

        /// <summary>
        /// 获取路径中文件名的首字母，用于Dictionary中的键
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static Char GetKey(String path)
        {
            return Char.ToUpper(path[path.LastIndexOf('\\') + 1]);// .ToString().ToUpper();
        }

        /// <summary>
        /// 创建项目文件版本信息
        /// </summary>
        /// <param name="entity"></param>
        public static void Create(Files entity)
        {
            sqlHelper.ExecuteNonQuery(String.Format(InsertSql,
                entity.ProjectName,
                entity.LastWriteTime,
                entity.Size,
                entity.Path,
                Services.SystemService.GetLocalIpv4(),
                Dns.GetHostName()
                ));
        }

        /// <summary>
        /// 删除项目文件版本信息
        /// </summary>
        /// <param name="entity"></param>
        public static void Remove(Files entity)
        {
            if (!String.IsNullOrWhiteSpace(entity.Path)) //路径不为空，使用路径删除
            {
                sqlHelper.ExecuteNonQuery(String.Format(DeleteSql, entity.ProjectName, entity.Path));
            }
        }

        /// <summary>
        /// 根据项目名称删除项目文件版本信息
        /// </summary>
        /// <param name="projectName"></param>
        //public static void Remove(String projectName)
        //{
        //    if (!String.IsNullOrWhiteSpace(projectName)) //项目名称不为空，使用项目名称删除
        //    {
        //        //删除逻辑存在问题，例如一个项目中有3个参与，此时其中一人退出项目组，删除路径时。项目数据不应受影响，现在由于数据量并不大的关系，可以考虑手动删除
        //        //Db.ExecuteNonQuery(String.Format(DeleteByProjectNameSql, projectName));
        //    }
        //}

        /// <summary>
        /// 修改项目文件版本信息
        /// </summary>
        /// <param name="entity"></param>
        public static void Modify(Files entity)
        {
            var sb = new StringBuilder("UPDATE [master].[dbo].[PublishFileVersion] SET");
            sb.AppendFormat("[LastWriteTime] = N'{0}'", entity.LastWriteTime);
            sb.AppendFormat(",[Size] = N'{0}'", entity.Size);
            sb.AppendFormat(",[ModifierIPv4] = N'{0}'", Services.SystemService.GetLocalIpv4());
            sb.AppendFormat(",[ModifierHostName] = N'{0}'", Dns.GetHostName());
            sb.Append(",[ModifiedTime] = GETDATE() ");
            sb.AppendFormat("WHERE [ProjectName] = N'{0}' And [Path] = N'{1}'", entity.ProjectName, entity.Path);

            sqlHelper.ExecuteNonQuery(sb.ToString());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        public static void SetChangeFile(Files entity)
        {

        }

        /// <summary>
        /// 根据Path获取项目文件版本信息
        /// </summary>
        /// <param name="path"></param>
        public static Files GetByPath(String path)
        {
            var dataTable = sqlHelper.GetDataSet(String.Format(GetFilesByPathSql, path));

            return modelHandler.FillModel(dataTable.Rows[0]);
        }

        /// <summary>
        /// 根据项目名称获取一条最后修改的数据
        /// </summary>
        /// <param name="projectName"></param>
        /// <returns></returns>
        public static String GetLastModifiedTimeByProjectName(String projectName)
        {
            var dataTable = sqlHelper.GetDataSet(String.Format(GetLastModifiedTimeSql, projectName));

            return dataTable.Rows.Count != 0
                ? dataTable.Rows[0]["ModifiedTime"].ToString()
                : String.Empty;
        }

        /// <summary>
        /// 根据项目名称获取该项目文件版本信息
        /// </summary>
        /// <param name="projectName">项目名称</param>
        /// <returns></returns>
        public static IDictionary<Char, List<Files>> GetAllFilesByProjectName(String projectName)
        {
            var dictionary = new Dictionary<Char, List<Files>>();

            var dataTable = sqlHelper.GetDataSet(String.Format(GetAllFilesByProjectNameSql, projectName));//获取文件版本信息

            var list = modelHandler.FillModel(dataTable);

            foreach (var item in list)
            {
                item.Path = item.Path.Trim();
                item.Type = Enum.CrudType.Normal;//默认为正常，在操作完成后统一执行时使用。
                var key = GetKey(item.Path);

                if (!dictionary.ContainsKey(key))//创建一个键
                    dictionary[key] = new List<Files>();

                dictionary[key].Add(item);//存入文件版本信息
            }

            return dictionary;
        }

        #endregion

        #region Private Method

        /// <summary>
        /// 更新项目文件版本数据，在完整发布后通过线程异步处理
        /// </summary>
        private static void Update()
        {
            foreach (var itemList in Publish.DictionaryList.Values)
            {
                foreach (var item in itemList.Where(x => x.Type != Enum.CrudType.Normal))
                {
                    if (item.Type == Enum.CrudType.C)
                    {
                        Create(item);//创建数据
                    }
                    else if (item.Type == Enum.CrudType.U)
                    {
                        Modify(item);//修改
                    }
                    else if (item.Type == Enum.CrudType.D)
                    {
                        Remove(item);//删除
                    }
                    item.Type = Enum.CrudType.Normal;//修改后，将状态重置
                }
            }
        }

        #endregion
    }
}
